/** 
* @Title: TraditionalThreadCommunication.java 
* @Package com.lh.threadtest.t4 
* @Description: TODO
* @author Liu 
* @date 2018年1月15日 下午9:28:23 
* @version V1.0 
*/
package com.lh.threadtest.t13;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/** 
* @ClassName: TraditionalThreadCommunication 
* @Description: java5阻塞队列的应用
* 
* 子线程循环10次，接着主线程循环100次，接着又回到子线程循环10次，接着再回到主线程
* 又循环100次，如此循环50次，请写出程序。
* 
* 说明：使用阻塞队列实现线程间的通信
* 
* @author Liu
* @date 2018年1月15日 下午9:28:23 
*  
*/
public class BlockingQueueCommunication {
	public static void main(String[] args) {
		final Business business = new Business();
		
		new Thread(new Runnable() {
			public void run() {
				for(int i = 1; i <= 50; i++){
					try {
						business.sub(i);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
		
		for(int i = 1; i <= 50; i++){
			try {
				business.main(i);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	//将具有类似功能的业务代码抽象到同一个类中
	//下面两个方法(sub/main)是互斥的，均是独立的一个同步模块，处于同一个互斥组(通过synchronized表明均属于同一个类，同一时刻只能有一个线程持有该锁)
	static class Business{
		BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(1);
		BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<>(1);
		
		//匿名构造方法，在任何构造方法执行前被调用
		{
			try {
				queue2.put(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		void sub(int i) throws InterruptedException{
			queue.put(1);
			
			for(int j = 1; j <= 10; j++){
				System.out.println("sub thread sequence of "  + j + ", loop of " + i);
			}
			
			queue2.take();
		}
		
		void main(int i) throws InterruptedException{
			queue2.put(1);
			
			for(int j = 1; j <= 100; j++){
				System.out.println("main thread sequence of "  + j + ", loop of " + i);
			}
			
			queue.take();
		}
	}
}


